<template>
  <div
    role="switch"
    class="v-switch flex"
    :class="{ disabled, checked }"
    :aria-checked="checked"
    :aria-disabled="disabled"
    @click.prevent="switchValue"
  >
    <input
      class="v-switch_input hidden"
      :class="{ checked }"
      type="checkbox"
      @change="handleChange"
      ref="input"
      :id="id"
      :name="name"
      :true-value="activeValue"
      :false-value="inactiveValue"
      :disabled="disabled"
      @keydown.enter="switchValue"
    />
    <span
      class="v-switch_core flex"
      :class="{ checked }"
      ref="core"
      :style="{ width: coreWidth + 'px' }"
    >
      <span class="v-switch_desc">{{ switchDesc }}</span>
    </span>
  </div>
</template>
<script>
export default {
  data() {
    return {
      coreWidth: this.width,
    };
  },
  props: {
    value: {},
    disabled: {
      type: Boolean,
      default: false,
    },
    activeValue: {
      type: [Boolean, String, Number],
      default: true,
    },
    inactiveValue: {
      type: [Boolean, String, Number],
      default: false,
    },
    width: {
      type: Number,
      default: 40,
    },
    activeColor: {
      type: String,
      default: "",
    },
    inactiveColor: {
      type: String,
      default: "",
    },
    activeText: {
      type: String,
      default: "",
    },
    inactiveText: {
      type: String,
      default: "",
    },
    name: {
      type: String,
      default: "",
    },
    id: String,
  },
  watch: {
    checked() {
      this.$refs.input.checked = this.checked;
      if (this.activeColor || this.inactiveColor) {
        this.setBackgroundColor();
      }
    },
  },
  computed: {
    checked() {
      return this.value === this.activeValue;
    },
    switchDesc() {
      return this.checked ? this.activeText : this.inactiveText;
    },
  },
  methods: {
    handleChange() {
      const val = this.checked ? this.inactiveValue : this.activeValue;
      this.$emit("input", val);
      this.$emit("change", val);
      this.$nextTick(() => {
        // set input's checked property
        // in case parent refuses to change component's value
        this.$refs.input.checked = this.checked;
      });
    },
    switchValue() {
      !this.disabled && this.handleChange();
    },
    setBackgroundColor() {
      let newColor = this.checked ? this.activeColor : this.inactiveColor;
      this.$refs.core.style.borderColor = newColor;
      this.$refs.core.style.backgroundColor = newColor;
    },
  },

  created() {
    if (!~[this.activeValue, this.inactiveValue].indexOf(this.value)) {
      this.$emit("input", this.inactiveValue);
    }
  },
  mounted() {
    if (this.activeColor || this.inactiveColor) {
      this.setBackgroundColor();
    }
    this.$refs.input.checked = this.checked;
  },
};
</script>
<style lang="less" scoped></style>
